package net.midnighttd.game;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedList;

import net.midnighttd.engine.entity.Entity;
import net.midnighttd.engine.Engine;

/**
 * Author: Adam Scarr
 * Date: 20/04/2009
 * Time: 10:19:04 AM
 */
public class Spawn {
    private LinkedList<Point> start = new LinkedList<Point>();
    private Point end;
    private ArrayList<Wave> waves = new ArrayList<Wave>();
    private long startTime;
    private long lastSpawn;
    private int width;
    private int height;
    private boolean spawn = false;

    public Spawn(Engine game, Element spawnElement) {
        NodeList waves = spawnElement.getElementsByTagName("wave");

        Point startPoint = game.getPoint(spawnElement.getAttribute("start"));
        start.add(startPoint);
        end = game.getPoint(spawnElement.getAttribute("end"));
        try {
            width = Integer.valueOf(spawnElement.getAttribute("width"));
        } catch (NumberFormatException e) {
            width = 1;
        }

        try {
            height = Integer.valueOf(spawnElement.getAttribute("height"));
        } catch (NumberFormatException e) {
            height = 1;
        }

        for(int x = 0; x < width; x++) {
            for(int y = 0; y < height; y++) {
                int rx = x - width / 2;
                int ry = y - height / 2;
                if(!(rx == 0 && ry == 0)) {
                    start.add(new Point(startPoint.x + rx, startPoint.y + ry));
                }
            }
        }

        for(int i = 0; i < waves.getLength(); i++) {
            if(waves.item(i).getNodeType() != Node.ELEMENT_NODE) continue;
            Element wave = (Element)waves.item(i);

            this.waves.add(new Wave(game, this, wave));
        }
    }

    public void startSpawning() {
        startTime = System.nanoTime();
        lastSpawn = startTime;
        spawn = true;
    }

    public void stopSpawning() {
        spawn = false;
    }

    public LinkedList<Entity> getSpawn() {
        if(!spawn) return new LinkedList<Entity>();
        
        long time = System.nanoTime();
        long spawnDuration = time - lastSpawn;
        long timeSinceStart = time - startTime;
        Wave currentWave = null;
        for(Wave wave: waves) {
            if((timeSinceStart - (wave.getDuration() + wave.getDelay())) > 0) {
                timeSinceStart -= (wave.getDuration() + wave.getDelay());
            } else {
                currentWave = wave;
                break;
            }
        }

        if(currentWave == null) return new LinkedList<Entity>();

        LinkedList<Entity> spawn = currentWave.getSpawn(timeSinceStart, spawnDuration);

        lastSpawn = time;
        
        return spawn;
    }

    public Point getStart() {
        return start.get((int)(Math.random() * start.size()));
    }

    public Point getEnd() {
        return end;
    }
}
